<?php
namespace EasySwoole\EasySwoole;


use App\Crontab\ClearToDayDateNumber;
use App\Crontab\DailyTask;
use App\Crontab\TaskOne;
use App\IpLimit\IpList;
use App\Middleware\AuthMiddleware;
use App\Middleware\SignValidationMiddleware;
use App\Middleware\TokenValidationMiddleware;
use App\Model\ManagerLog;
use App\Model\Task;
use App\Process\HotReload;
use App\Process\IpAccessCount;
use App\Process\Lottery;
use App\Process\Consume;
use App\Process\Master;
use App\Process\RunProcess;
use App\Task\RunTask;
use App\Utility\Encryptor;
use App\Utility\Register;
use App\Utility\TxWebService;
use App\Utility\WechatService;
use App\WebSocket\WebSocketEvent;
use App\WebSocket\WebSocketParser;
use EasySwoole\Component\Context\ContextManager;
use EasySwoole\Component\Process\AbstractProcess;
use EasySwoole\EasySwoole\Crontab\Crontab;
use EasySwoole\EasySwoole\Swoole\EventRegister;
use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Task\TaskManager;
use EasySwoole\Http\Request;
use EasySwoole\Http\Response;
use EasySwoole\Jwt\Jwt;
use EasySwoole\Mysqli\QueryBuilder;
use EasySwoole\RedisPool\Redis;
use EasySwoole\Session\Session;
use EasySwoole\Session\SessionFileHandler;
use EasySwoole\Socket\Dispatcher;
use EasySwoole\Component\Process\Config;
use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Db\Connection;
use EasySwoole\ORM\Db\Config as DbConfig;
use EasySwoole\EasySwoole\Config as SystemConfig;
use EasySwoole\WeChat\Bean\OfficialAccount\Message\News;
use EasySwoole\WeChat\Bean\OfficialAccount\Message\Text;
use EasySwoole\WeChat\Bean\OfficialAccount\RequestConst;
use EasySwoole\WeChat\Bean\OfficialAccount\RequestMsg;
use EasySwoole\WeChat\WeChat;
use App\Crontab\ActivityTask;

class EasySwooleEvent implements Event
{

    public static function initialize()
    {

        date_default_timezone_set('Asia/Shanghai');

        $instance = SystemConfig::getInstance();
        $mysqlConf = $instance->getConf('MYSQL');
        $config = new DbConfig();
        $config->setDatabase($mysqlConf['database']);
        $config->setUser($mysqlConf['user']);
        $config->setPassword($mysqlConf['password']);
        $config->setHost($mysqlConf['host']);
        $config->setPort($mysqlConf['port']);
        $config->setMaxObjectNum($mysqlConf['pool_max_num']);
        $config->setMinObjectNum($mysqlConf['pool_min_num']);
        $config->setIntervalCheckTime($mysqlConf['interval_check_time']*1000);
        DbManager::getInstance()->addConnection(new Connection($config));


        $instance = SystemConfig::getInstance();
        $mysqlConf = $instance->getConf('MYSQL_SLAVE');
        $config = new DbConfig();
        $config->setDatabase($mysqlConf['database']);
        $config->setUser($mysqlConf['user']);
        $config->setPassword($mysqlConf['password']);
        $config->setHost($mysqlConf['host']);
        $config->setPort($mysqlConf['port']);
        $config->setMaxObjectNum($mysqlConf['pool_max_num']);
        $config->setMinObjectNum($mysqlConf['pool_min_num']);
        $config->setIntervalCheckTime($mysqlConf['interval_check_time']*1000);
        DbManager::getInstance()->addConnection(new Connection($config),'read');
    }

    public static function mainServerCreate(EventRegister $register)
    {
        $register->add($register::onWorkerStart,function (){
            //链接预热
            DbManager::getInstance()->getConnection()->getClientPool()->keepMin();

        });
        IpList::getInstance();
        $processConfig = new Config();
        $processConfig->setProcessName('IpAccessCount');
        ServerManager::getInstance()->getSwooleServer()->addProcess((new  IpAccessCount($processConfig))->getProcess());

        $processConfig = new Config();
        $processConfig->setProcessName('RunProcess');
        ServerManager::getInstance()->getSwooleServer()->addProcess((new  RunProcess($processConfig))->getProcess());

        if(Core::getInstance()->isDev()){
            $swooleServer = ServerManager::getInstance()->getSwooleServer();
            $swooleServer->addProcess((new HotReload('HotReload', ['disableInotify' => false]))->getProcess());
        }

        //ws
        $conf = new \EasySwoole\Socket\Config();
        $conf->setType(\EasySwoole\Socket\Config::WEB_SOCKET);
        $conf->setParser(new WebSocketParser());
        $dispatch = new Dispatcher($conf);
        $register->set(EventRegister::onMessage, function (\swoole_websocket_server $server, \swoole_websocket_frame $frame) use ($dispatch) {
            $dispatch->dispatch($server, $frame->data, $frame);
        });

        $websocketEvent = new WebSocketEvent();
        $register->set(EventRegister::onHandShake, function (\swoole_http_request $request, \swoole_http_response $response) use ($websocketEvent) {
            $websocketEvent->onHandShake($request, $response);
        });

        $register->set(EventRegister::onClose, function (\swoole_server $server, int $fd, int $reactorId) use ($websocketEvent) {
            $websocketEvent->onClose($server, $fd, $reactorId);
        });

        Crontab::getInstance()->addTask(DailyTask::class);
        //连接池
        $instance = SystemConfig::getInstance();
        $conf = $instance->getConf('REDIS');
        $redisConfig = new \EasySwoole\Redis\Config\RedisConfig();
        $redisConfig->setAuth($conf['auth']);
        $redisConfig->setDb($conf['db_index']);
        $redisPoolConfig= Redis::getInstance()->register('redis',$redisConfig);
        $redisPoolConfig->setMinObjectNum($conf['pool_min_num']);
        $redisPoolConfig->setMaxObjectNum($conf['pool_max_num']);
        $redisPoolConfig->setAutoPing($conf['interval_check_time']);
        //注册腾讯云API
        $txmapKey = $instance->getConf('tx_map.key');
        TxWebService::getInstance($txmapKey);
        //注册JWT
        $jwtObject = Jwt::getInstance()
            ->setSecretKey(\EasySwoole\EasySwoole\Config::getInstance()->getConf('salt'))
            ->publish();


        $handler = new SessionFileHandler(EASYSWOOLE_TEMP_DIR);
        Session::getInstance($handler,'kybc_sess');


    }

    public static function onRequest(Request $request, Response $response): bool
    {


        $response->withHeader('Access-Control-Allow-Origin', '*');
//        $response->withHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
        $response->withHeader('Access-Control-Allow-Credentials', 'true');
//        $response->withHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With');
//        if ($request->getMethod() === 'OPTIONS') {
//            $response->withStatus(Status::CODE_OK);
//            return false;
//        }

        ContextManager::getInstance()->set('request',$request);
        ContextManager::getInstance()->set('response',$response);
        $route  = $request->getUri()->getPath();

//        $res = IpList::getInstance()->verification($request);
//        if(!$res){
//            return false;
//        }

        $res = TokenValidationMiddleware::getInstance()->verification($request);
        if(!$res){
            return false;
        }

        //验证签名
        if(!Core::getInstance()->isDev()){
            $res = SignValidationMiddleware::getInstance()->verification($request);
            if(!$res){
                return false;
            }
        }



        $res = AuthMiddleware::getInstance()->verification($request);
        if(!$res){
            return false;
        }

        $params = $request->getRequestParam();

        $ip  = ServerManager::getInstance()->getSwooleServer()->connection_info($request->getSwooleRequest()->fd)['remote_ip']?:$request->getHeader('x-real_ip');
        unset($params['token']);
        Logger::getInstance()->info("[{$route}][{$ip}][params]".PHP_EOL.var_export($params,true).PHP_EOL);

        return true;
    }

    public static function afterRequest(Request $request, Response $response): void
    {

        // TODO: Implement afterAction() method.
    }
}